package com.example.android.debuggermenu;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import clientcore.GameState;
import clientcore.Message;

import android.app.ListActivity;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Friends extends ListActivity {

	public static final String TAG = Friends.class.getSimpleName();
	private AlertDialog.Builder builder;
	private AlertDialog addDialog, deleteDialog, chatDialog, alertDialog;
	private Context mContext = this;
	private HashMap<String, Boolean> buds;
	private Integer numOfChats = 0;
	private Integer numOfInvites = 0;
	//private Vector<Message> inviteMessages;
	private ArrayList<String> friends;
	private String addName, deleteName;
	private Intent inviteIntent = null;
	private String username, message;
	private ArrayAdapter<String> myAdapter;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("DEBUG", "Set List Adapter");
        //getListView().setTextFilterEnabled(true);
        
        /*BRIAN an example of retrieving friends   
        HashMap<String, Boolean> buds = GameState.getBuddies();
        if(buds != null) {
		    for(String name : buds.keySet()) {
		    	Log.d("Friends", name + " " + (buds.get(name)? "online" : "offline"));
		    }
        }
        */
        /*
        //An example of inviting friends
        // status
        // -1 does not exist
        // 0 offline
        // 1 invite sent
         * 
         */
        /*
        short status = GameState.inviteBuddy("manori", "Join me or die!");
        Log.d(TAG, "Status: " + status);
        status = GameState.inviteBuddy("ameya", "Join me or die!");
        Log.d(TAG, "Status: " + status);
        status = GameState.inviteBuddy("ejfai3823j", "Join me or die!");
        Log.d(TAG, "Status: " + status);
        */

        /*Get a list of invites */
        //Vector<Message> messages = GameState.updateBuddyInvites();
        //for(Message m : messages) {
        //	Log.d("BUDDY INVITES", "SENDER: " + m.getSender() + " MESSAGE: " + m.getText());
        //}

        /* Send private chats */
        //status = GameState.sendPrivateChat("manori", "I am chatting you!");
        //status = GameState.sendPrivateChat("manori", "You are being chatted!");
    
        /* Get private chats */
        //messages = GameState.updatePrivateChats();
        //for(Message m : messages) {
        //	Log.d("CHATS", "SENDER: " + m.getSender() + " MESSAGE: " + m.getText());
        //}
        
        /*Add a buddy */
        //GameState.respondToInvite("manori", true);
        
        /*Remove a buddy */
        //GameState.removeBuddy("ameya");
    }
    
    public void onResume() {
    	super.onResume();
    	Log.d("Friends", "Start AsyncTask");
        new loadData().execute(); //execute asynctask to retreive buddy list
        Log.d("Friends", "AsycTask finished");
    }
    
    //Defines what will happen when one of the list items (friends) is clicked
    //In this case, a dialog box asking if the user wants to send a message appears
    public void onListItemClick(ListView parent, View v, int position, long id) {
    	showChat(position);
    }
    
    public boolean getOnlineStatus(String name) {
    	return buds.get(name);
    }
    
    //Creates the menu
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.friends_menu, menu);
    	return true;
    }
    
    //Assigns what will be executed when a menu button is pressed
    public boolean onOptionsItemSelected(MenuItem item) {
    	Bundle listBundle = new Bundle();
    	
    	switch (item.getItemId()) {
    	case R.id.add:
    		showAdd();
    		return true;
    	case R.id.delete:
    		showDelete();
    		return true;
    	case R.id.invites:
    		inviteIntent = new Intent(this, InviteList.class);
    		startActivity(inviteIntent);
    		return true;
    	default:
    		return super.onOptionsItemSelected(item);
    	}
    }
    
    public void showChat(int position) {
    	username = (String) getListView().getItemAtPosition(position);
		View friendsChat = this.getLayoutInflater().inflate(R.layout.single_chat_dialog, (ViewGroup)findViewById(R.id.single_chat_dialog));
		builder = new AlertDialog.Builder(this);
		builder.setView(friendsChat);
				       
		final TextView sn = (TextView) friendsChat.findViewById(R.id.chat1_username);
	    final EditText chatBox = (EditText) friendsChat.findViewById(R.id.chat1_edit_txt);
	    final Button chatSend = (Button) friendsChat.findViewById(R.id.chat1_sendButton);
	    final Button chatCancel = (Button) friendsChat.findViewById(R.id.chat1_cancelButton);		       
		
	    sn.setText("To: " + username);
	 
	    chatSend.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				message = chatBox.getText().toString();
				long status = GameState.sendPrivateChat(username, message);
				if (status == -1) {
					chatDialog.dismiss();
					Toast.makeText(mContext, "Invalid username", Toast.LENGTH_SHORT).show();
				} else if (status == 0) {
					chatDialog.dismiss();
					Toast.makeText(mContext, username + " is offline", Toast.LENGTH_SHORT).show();
				} else if (status == 1) {
					chatDialog.dismiss();
					Toast.makeText(mContext, "Message sent to:\n" + username, Toast.LENGTH_SHORT).show();
				}
			}
	    });
	    
	    chatCancel.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				chatDialog.dismiss();
			}
		});
	    chatDialog = builder.create();
	    chatDialog.show();
    }
    
    //************************************************************
    //Displays a dialog box to delete a friend to your buddy list
    //************************************************************
    public void showDelete() {
    	deleteName = null;
    	
    	View deleteFriendsDialog = this.getLayoutInflater().inflate(R.layout.friends_dialog, (ViewGroup)findViewById(R.id.add_dialog));
    	builder = new AlertDialog.Builder(this);
    	builder.setView(deleteFriendsDialog);
    	
    	final TextView title = (TextView)deleteFriendsDialog.findViewById(R.id.username);
    	final EditText textBox = (EditText)deleteFriendsDialog.findViewById(R.id.nameEditText);
    	final Button deleteButton = (Button)deleteFriendsDialog.findViewById(R.id.okButton);
    	deleteButton.setText("Delete");
    	final Button cancelButton = (Button)deleteFriendsDialog.findViewById(R.id.cancelButton);
    	
    	deleteButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				deleteName = textBox.getText().toString();
				short status = GameState.removeBuddy(deleteName);
				if (status == 1) {
					int position;
					for (position = 0; position < friends.size(); position++) {
						if (friends.get(position).equals(deleteName)) {
							friends.remove(position);
							break;
						}
					}
					deleteDialog.dismiss();
					Toast.makeText(mContext, deleteName + " is no longer your friend :(", Toast.LENGTH_SHORT).show();
					myAdapter.notifyDataSetChanged();
				} else if (status == 0) {
					deleteDialog.dismiss();
					Toast.makeText(mContext, deleteName + " is not on your buddy list", Toast.LENGTH_SHORT).show();
				}
			}
		});
    	
    	cancelButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				deleteDialog.dismiss();
			}
		});
    	deleteDialog = builder.create();
    	deleteDialog.show();
    }
    
    //***************************************************
    //Displays a dialog box to add a friend to your buddy list
    //***************************************************
    public void showAdd() {
    	addName = null;
    	builder = new AlertDialog.Builder(this);
    	
    	View addFriendsDialog = this.getLayoutInflater().inflate(R.layout.friends_dialog, (ViewGroup)findViewById(R.id.add_dialog));
    	builder.setView(addFriendsDialog);
    	
    	final TextView title = (TextView)addFriendsDialog.findViewById(R.id.username);
    	final EditText textBox = (EditText)addFriendsDialog.findViewById(R.id.nameEditText);
    	final Button addButton = (Button)addFriendsDialog.findViewById(R.id.okButton);
    	addButton.setText("Add");
    	final Button cancelButton = (Button)addFriendsDialog.findViewById(R.id.cancelButton);
    	
    	addButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				boolean alreadyFriend = false;
				addName = textBox.getText().toString();
				
		    	for (int i = 0; i < friends.size(); i++) {
					if (addName.equals(friends.get(i))) {
						alreadyFriend = true;
						break;
					}
				}
				if (alreadyFriend == false) {
					Log.d(TAG, "send to: " + addName);
					short status = GameState.inviteBuddy(addName, "Join me or die!");
					Log.d(TAG, "status: " + status);
					if (status == -1) {
						addDialog.dismiss();
						Toast.makeText(mContext, "Invalid username", Toast.LENGTH_SHORT).show();
					} else if (status == 0) {
						addDialog.dismiss();
						Toast.makeText(mContext, addName + " is offline", Toast.LENGTH_SHORT).show();
					} else if (status == 1) {
						addDialog.dismiss();
						Toast.makeText(mContext, "Invite sent to:\n" + addName, Toast.LENGTH_SHORT).show();
					}
				} else {
					addDialog.dismiss();
					AlertDialog.Builder newbuilder = new AlertDialog.Builder(mContext);
					newbuilder.setMessage(addName + " is already your friend!")
						.setCancelable(false)
						.setNeutralButton("Close", new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int which) {
								alertDialog.dismiss();
							}
						});
					alertDialog = newbuilder.show();
				}
			}
		});
    	
    	cancelButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				addDialog.dismiss();
			}
		});
    	addDialog = builder.create();
    	addDialog.show();
    }
    
    //******************************************************
    //Returns a String[] of the keys in a hashmap
    //Will return an array of all of the players friends names
    //******************************************************
    public ArrayList<String> getNameList(HashMap<String, Boolean> map) {
    	String[] array = (String[]) map.keySet().toArray(new String[map.size()]);
    	ArrayList<String> list = new ArrayList<String>();
    	for (int i = 0; i < array.length; i++) {
    		list.add(array[i]);
    	}
    	
    	return list;
    }
    
    //******************************************************
    //Custom row adapter to allow for a custom list view
    //******************************************************
    class FriendRowAdapter extends ArrayAdapter<String> {
    	private ArrayList<String> friendList;
    	
		public FriendRowAdapter(Context context, int textViewResourceId, ArrayList<String> items) {
    		//super(Friends.this, R.layout.friends_row, R.id.username, friends);
			super(context, textViewResourceId, items);
			this.friendList = items;
		}
    	
    	public View getView(int position, View convertView, ViewGroup parent) {
    		//View row = super.getView(position, convertView, parent);
    		View v = convertView;
    		if (v == null) {
    			LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    			v = vi.inflate(R.layout.friends_row, null);
    		}
    		String name = friendList.get(position);
    		TextView viewName = (TextView) v.findViewById(R.id.username);
    		viewName.setText(name);
    		ImageView status = (ImageView) v.findViewById(R.id.status);
    		if (getOnlineStatus(name) == true) {
    			status.setImageResource(R.drawable.online);
    		} else {
    			status.setImageResource(R.drawable.offline);
    		}
    		return v;
    	}
    }
    
    //****************************************************
    //Starts a new thread that loads a buddy list
    //****************************************************
    private class loadData extends AsyncTask<Void, Void, HashMap<String, Boolean>> {
		private ProgressDialog dialog;
 
		protected void onPreExecute() {
			Log.d("LoadBuddies", "begin onPreExecute");
			dialog = new ProgressDialog(mContext);
			dialog.setMessage("Loading Buddy List...");
			dialog.setCancelable(false); 
			dialog.show();
		}
		
		@Override
		protected HashMap<String, Boolean> doInBackground(Void... arg0) {
			Log.d("LoadBuddies", "begin doInBackground");
			
			Vector<Message> chatMessages = GameState.updatePrivateChats();
			Log.d("getChats", "connection made");
			for(Message m : chatMessages) {
		      	Log.d("CHATS", "SENDER: " + m.getSender() + " MESSAGE: " + m.getText());
		      	GameState.addMessage(m);
		    }
			numOfChats = chatMessages.size();
			chatMessages.clear();
			
			Vector<Message> inviteMessages = GameState.updateBuddyInvites();
			Log.d("LoadBuddies", "connection made for invites");
			for(Message m : inviteMessages) {
	        	Log.d("BUDDY INVITES", "SENDER: " + m.getSender() + " MESSAGE: " + m.getText());
	        	GameState.addInvite(m);
	        }
			numOfInvites = inviteMessages.size();
			inviteMessages.clear();
			
            buds = GameState.getBuddies();
            if(buds != null) {
    		    for(String name : buds.keySet()) {
    		    	Log.d("Friends", name + " " + (buds.get(name)? "online" : "offline"));
    		    }
            }
            
            friends = getNameList(buds);
			return buds;
		}
		
		protected void onPostExecute(HashMap<String, Boolean> result) {
			Log.d("LoadBuddies", "begin onPostExecute");
			if (numOfChats > 0) {
				Toast.makeText(mContext, numOfChats + " new messages!", Toast.LENGTH_LONG).show();
			}
			if (numOfInvites > 0) {
				Toast.makeText(mContext, numOfInvites + " new invites!", Toast.LENGTH_LONG).show();
			}
			setContentView(R.layout.friend_layout);
			myAdapter = new FriendRowAdapter(mContext, R.layout.friends_row, friends);
			setListAdapter(myAdapter);
			dialog.dismiss();
		}
	}
    
}
